package com.broada.apm.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broada.apm.ajax.ApplicationResult;
import com.broada.apm.ajax.PerformanceResult;
import com.broada.apm.base.BaseService;
import com.broada.apm.entity.AO;
import com.broada.apm.entity.ApplicationSystem;
import com.broada.apm.entity.Relation;
import com.broada.apm.entity.Service;
import com.broada.apm.entity.TopoNode;
import com.broada.apm.service.ApplicationService;
import com.broada.apm.utils.ApmFileUtils;
import com.broada.apm.utils.ConfigureProperties;
import com.broada.apm.utils.EsClientUtil;
import com.broada.apm.utils.ExceptionUtils;
import com.broada.apm.utils.RestClientUtil;

public class ApplicationServiceImpl extends BaseService implements ApplicationService {
    private static final Logger LOG = LoggerFactory.getLogger(ApplicationServiceImpl.class);
	@Override
	public ApplicationResult queryApplications() {
		ApplicationResult result = new ApplicationResult();
		List<ApplicationSystem> list = appLogic.queryApplications();
		result.setApplications(list);
		return result;
	}

	@Override
	public ApplicationResult queryApplication(String appId, String panelId) {
		ApplicationResult result = new ApplicationResult();
		if (StringUtils.isBlank(panelId)) {
			result.setFailMessage("参数错误");
			return result;
		}
		ApplicationSystem app = appLogic.queryApplicationById(appId, panelId);
		if (app == null) {
			result.setFailMessage("应用系统不存在");
			return result;
		}
		result.setApplication(app);
		return result;
	}

	@Override
	public ApplicationResult addApplicationNameAndApdex(HashMap<String, String> map) {
		ApplicationResult result = new ApplicationResult();
		if (map != null) {
			try {
				appLogic.addApplicationNameAndApdex(map);
			} catch (Exception e) {
				result.setFailMessage("添加应用系统名称和Apdex失败");
			}
		}
		return result;
	}

	@Override
	public ApplicationResult deleteApplicationById(String appId) {
		ApplicationResult result = new ApplicationResult();
		if (StringUtils.isNotBlank(appId)) {
			appLogic.deleteApplicationById(decoderString(appId));
			// 删除ES数据库中应用系统的应用性能数据
	        RestClientUtil.doAction(RestClientUtil.METHOD_DELETE, EsClientUtil.getEsHttpUrl() + "/apm_perf_a" + appId +"*", null);
            RestClientUtil.doAction(RestClientUtil.METHOD_DELETE, EsClientUtil.getEsHttpUrl() + "/apm_error_a" + appId +"*", null);
            try {
                FileUtils.deleteDirectory(ApmFileUtils.getFile(ConfigureProperties.getString("errorr.detail.dir", "../error.detail/")+appId));
            } catch (IOException e) {
                ExceptionUtils.error(LOG, "清理错误日志目录出错", e);
                result.setFailMessage("清理错误日志目录出错");
            }
		}
		return result;
	}

	@Override
	public ApplicationResult updateApplicationNameAndApdex(HashMap<String, String> map) {
		ApplicationResult result = new ApplicationResult();
		if (map != null) {
			try {
				appLogic.updateApplicationNameAndApdex(map);
			} catch (Exception e) {
				result.setFailMessage("更新应用系统名称和Apdex失败");
			}
		}
		return result;
	}

	@Override
	public ApplicationResult saveApplicationTopology(String appId, ApplicationSystem app) {
		ApplicationResult result = new ApplicationResult();
		if (StringUtils.isBlank(appId) || app == null) {
			result.setFailMessage("保存失败");
			return result;
		}
		try {
			TopoNode topoNode = appLogic.saveApplicationTopology(appId, app);
			result.setNodes(topoNode.getNodes());
			result.setRelations(topoNode.getRelations());
		} catch (Exception e) {
			result.addData("fail", "保存失败");
			result.setFailMessage(e.getMessage());
			ExceptionUtils.error(LOG,"保存应用系统失败",e);
		}
		return result;
	}

	@Override
	public ApplicationResult deleteApplicationTopologyNodesByNodeIds(String appId, String nodeId) {
		ApplicationResult result = new ApplicationResult();
		nodeId = decoderString(nodeId);
		if (!appLogic.deleteApplicationTopologyNodesByNodeIds(appId, nodeId))
			result.setFailMessage("节点删除失败");
		return result;
	}

	@Override
	public ApplicationResult saveApplicationTopologyNodes(String appId, List<Service> list, String panelId) {
		ApplicationResult result = new ApplicationResult();
		List<Service> services = null;
		try {
			services = appLogic.saveTopologyNodesAndCluster(appId, list, panelId);
		} catch (Exception e) {
			result.setFailMessage(e.getMessage());
		}
		result.setTopoNode(services);
		return result;
	}

	@Override
	public ApplicationResult queryApplicationTopologyRelations(String appId, String nodeIds) {
		String[] arrNodeIds = decoderArry(nodeIds);
		ApplicationResult result = new ApplicationResult();
		List<Relation> relas = appLogic.queryApplicationTopologyRelations(appId, arrNodeIds);
		result.setRelations(relas);
		return result;
	}

	@Override
	public ApplicationResult changeOrder(HashMap<String, String> ids) {
		ApplicationResult result = new ApplicationResult();
		if (StringUtils.isEmpty(ids.get("id1")) || StringUtils.isEmpty(ids.get("id2"))) {
			result.setFailMessage("参数有误");
		}
		if (!appLogic.changeApplicationOrder(ids.get("id1"), ids.get("id2"))) {
			result.setFailMessage("处理失败");
		}
		return result;
	}

	@Override
	public ApplicationResult queryAOSByAppId(String appId, String panelId) {
		ApplicationResult result = new ApplicationResult();
		List<AO> aos = appLogic.queryAOSByAppId(appId, panelId);
		result.setAos(aos);
		return result;
	}

	@Override
	public ApplicationResult queryProtocalByAppId(String appId) {
		ApplicationResult result = new ApplicationResult();
		ApplicationSystem application = appLogic.getApplicationInfoById(appId);
		if (application == null) {
			result.setFailMessage("应用系统不存在");
			return result;
		}
		List<String> list = appLogic.queryApplicaitonProtocals(application);
		result.setProtocal(list);
		
		return result;
	}

	@Override
	public ApplicationResult queryIpsByAppId(String appId) {
		ApplicationResult result = new ApplicationResult();
		ApplicationSystem application = appLogic.getApplicationInfoById(appId);
		if (application == null) {
			result.setFailMessage("应用系统不存在");
			return result;
		}
		List<String> list = appLogic.queryApplicaitonIps(application);
		result.setIps(list);
		
		return result;
	}

	@Override
	public PerformanceResult queryAppsInOverview(boolean inOverview, String keyWord, long startDate, long endDate) {
		PerformanceResult result = new PerformanceResult();
		try {
			List<ApplicationSystem> appList = appLogic.getApplicationByCondition(inOverview, keyWord);
			result.setApplications(appList);
		} catch (Exception e) {
			LOG.error(e.getMessage());
			result.setFailMessage("查询交易总览页面应用系统失败");
		}
		return result;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public ApplicationResult appInOrOutOverview(HashMap<String, Object> map) {
		ApplicationResult result = new ApplicationResult();
		try {
			if(map.isEmpty()){
				return result;
			}
			ApplicationSystem application = new ApplicationSystem();
			application.setIsOverview((boolean)map.get("isOverview"));
			List<String> appIds = (List) map.get("appIds");
			if(appIds != null && appIds.size() > 0){
				for(String id:appIds){
					application.setId(id);
					appLogic.updateAppOverviewStatus(application);
				}
			}
		} catch (Exception e) {
			LOG.error(e.getMessage());
			result.setFailMessage("添加或删除交易总览页面应用系统失败");
		}
		return result;
		
	}

	@Override
	public ApplicationResult saveAppsInOverview(List<String> appIds) {
		ApplicationResult result = new ApplicationResult();
		try {
			appLogic.saveAppsInOverview(appIds);
		} catch (Exception e) {
			LOG.error(e.getMessage());
			result.setFailMessage("添加或删除交易总览页面应用系统失败");
		}
		return result;
	}

	@Override
	public ApplicationResult businessChangeOrder(HashMap<String, String> ids) {
		ApplicationResult result = new ApplicationResult();
		if (StringUtils.isEmpty(ids.get("id1")) || StringUtils.isEmpty(ids.get("id2"))) {
			result.setFailMessage("参数有误");
		}
		if (!appLogic.changeBusinessApplicationOrder(ids.get("id1"), ids.get("id2"))) {
			result.setFailMessage("处理失败");
		}
		return result;
	}

}
